package com.gitee.wsl.compose.chart.polar


import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.layout.Layout
import com.gitee.wsl.compose.chart.Chart
import com.gitee.wsl.compose.chart.ExperimentalKoalaPlotApi
import com.gitee.wsl.compose.chart.polar.layout.PolarGraphMeasurePolicy
import com.gitee.wsl.compose.chart.polar.axis.AngularAxisModel
import com.gitee.wsl.compose.chart.polar.axis.FloatRadialAxisModel
import com.gitee.wsl.compose.chart.xy.axis.AxisLabel
import com.gitee.wsl.compose.chart.polar.style.PolarGraphDefaults
import com.gitee.wsl.compose.chart.polar.style.PolarGraphStyle
import com.gitee.wsl.compose.ui.container.hoverable.HoverableElementArea


/**
 * A Graph using polar coordinates - a radial axis and an angular axis.
 * Multiple series of data can be plotted on a polar graph as lines and/or shaded regions with or without
 * symbols at each plotted point.
 *
 * @param T The data type for the angular axis
 * @param radialAxisModel Provides the radial axis coordinate system
 * @param angularAxisModel An [AngularAxisModel] providing the angular axis coordinate system
 * @param radialAxisLabels [Composable] providing radial axis labels.
 * @param angularAxisLabels [Composable] providing angular axis labels.
 * @param polarGraphStyle Properties to customize plot styling.
 * @param content Content to display on the plot, see [PolarPlotSeries].
 */
@ExperimentalKoalaPlotApi
@Composable
 fun <T> Chart.PolarGraph(
    radialAxisModel: FloatRadialAxisModel,
    angularAxisModel: AngularAxisModel<T>,
    radialAxisLabels: @Composable (Float) -> Unit,
    angularAxisLabels: @Composable (T) -> Unit,
    modifier: Modifier = Modifier,
    polarGraphStyle: PolarGraphStyle = PolarGraphDefaults.Default(),
    content: @Composable PolarGraphScope<T>.() -> Unit
) {
    HoverableElementArea(modifier = modifier) {
        /*val scope = object : PolarGraphScope<T>, HoverableElementAreaScope by this {
            override val radialAxisModel = radialAxisModel
            override val angularAxisModel = angularAxisModel
            override fun polarToCartesian(point: PolarPoint<Float, T>, size: Size): Offset {
                return polarToCartesianPlot(point, angularAxisModel, radialAxisModel, size)
            }
        }*/

        with(PolarGraphScopeImp(radialAxisModel,angularAxisModel,this)){
            Layout(
                contents = buildList {
                    add { Grid(polarGraphStyle) }
                    add {
                        radialAxisModel.tickValues.forEach {
                            Box { radialAxisLabels(it) }
                        }
                    }
                    add {
                        angularAxisModel.getTickValues().forEach {
                            Box { angularAxisLabels(it) }
                        }
                    }
                    add {
                        Box(
                            modifier = Modifier.drawWithContent {
                                val clipPath = generateGridBoundaryPath(size, polarGraphStyle.radialGridType)
                                clipPath(clipPath) {
                                    this@drawWithContent.drawContent()
                                }
                            }
                        ) { content() }
                    }
                },
                measurePolicy = PolarGraphMeasurePolicy(angularAxisModel, radialAxisModel, polarGraphStyle)
            )
        }
    }
}




/**
 * A Graph using polar coordinates - a radial axis and an angular axis.
 * Multiple series of data can be plotted on a polar graph as lines and/or shaded regions with or without
 * symbols at each plotted point.
 *
 * @param T The data type for the angular axis
 * @param radialAxisModel Provides the radial axis coordinate system
 * @param angularAxisModel An [AngularAxisModel] providing the angular axis coordinate system
 * @param radialAxisLabelText Provides strings for radial axis labels.
 * @param angularAxisLabelText Provides strings for angular axis labels.
 * @param polarGraphStyle Properties to customize plot styling.
 * @param content Content to display on the plot, see [PolarPlotSeries].
 */
@ExperimentalKoalaPlotApi
@Composable
 fun <T> Chart.PolarGraph(
    radialAxisModel: FloatRadialAxisModel,
    angularAxisModel: AngularAxisModel<T>,
    radialAxisLabelText: (Float) -> String = radialAxisModel::label,
    angularAxisLabelText: (T) -> String = angularAxisModel::label,
    modifier: Modifier = Modifier,
    polarGraphStyle: PolarGraphStyle = PolarGraphDefaults.Default(),
    content: @Composable PolarGraphScope<T>.() -> Unit
) {
    PolarGraph(
        radialAxisModel,
        angularAxisModel,
        radialAxisLabels = {
            /*Text(
                radialAxisLabelText(it),
                color = MaterialTheme.colorScheme.onBackground,
                style = MaterialTheme.typography.bodySmall
            )*/
            AxisLabel(label = radialAxisLabelText(it))
        },
        angularAxisLabels = {
            /*Text(
                angularAxisLabelText(it),
                color = MaterialTheme.colorScheme.onBackground,
                style = MaterialTheme.typography.bodySmall
            )*/
            AxisLabel(label = angularAxisLabelText(it))
        },
        modifier,
        polarGraphStyle,
        content
    )
}

